home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / testdisk / src / ext2_dir.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-01-09  |  8.5 KB  |  297 lines

  1. /*
  2.  
  3.     File: ext2_dir.c
  4.  
  5.     Copyright (C) 1998-2004 Christophe GRENIER <grenier@cgsecurity.org>
  6.   
  7.     This software is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.   
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.   
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  */
  22. #ifdef HAVE_E2FSPROGS
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #include <stdlib.h>
  27. #include <time.h>
  28. #include <sys/stat.h>
  29. #include "ext2fs/ext2_fs.h"
  30. #include "ext2fs/ext2fs.h"
  31. #include "types.h"
  32. #include "common.h"
  33. #include "intrface.h"
  34. #include "dir.h"
  35. #include "ext2_dir.h"
  36.  
  37. #define DIRENT_DELETED_FILE    4
  38. /*
  39.  * list directory
  40.  */
  41.  
  42. #define LONG_OPT    0x0001
  43.  
  44. struct list_dir_struct {
  45.     t_file_data *dir_list;
  46.     t_file_data *current_file;
  47.     ext2_filsys current_fs;
  48.     int flags;
  49. };
  50.  
  51.  
  52. /*
  53.  * I/O Manager routine prototypes
  54.  */
  55. static errcode_t my_open(const char *dev, int flags, io_channel *channel);
  56. static errcode_t my_close(io_channel channel);
  57. static errcode_t my_set_blksize(io_channel channel, int blksize);
  58. static errcode_t my_read_blk(io_channel channel, unsigned long block, int count, void *buf);
  59. static errcode_t my_write_blk(io_channel channel, unsigned long block, int count, const void *buf);
  60. static errcode_t my_flush(io_channel channel);
  61.  
  62.  
  63. static io_channel alloc_io_channel(t_param_disk *disk_car,t_diskext *partition);
  64.  
  65. static struct struct_io_manager my_struct_manager = {
  66.         magic: EXT2_ET_MAGIC_IO_MANAGER,
  67.         name: "TestDisk I/O Manager",
  68.         open: my_open,
  69.         close: my_close,
  70.         set_blksize: my_set_blksize,
  71.         read_blk: my_read_blk,
  72.         write_blk: my_write_blk,
  73.         flush: my_flush,
  74.     write_byte: NULL
  75. };
  76.  
  77. io_manager my_io_manager = &my_struct_manager;
  78. /*
  79.  * Macro taken from unix_io.c
  80.  * For checking structure magic numbers...
  81.  */
  82.  
  83. #define EXT2_CHECK_MAGIC(struct, code) \
  84.           if ((struct)->magic != (code)) return (code)
  85.  
  86. /*
  87.  * Allocate libext2fs structures associated with I/O manager
  88.  */
  89. static io_channel alloc_io_channel(t_param_disk *disk_car,t_diskext *partition)
  90. {
  91.   io_channel     ioch;
  92.   t_my_data    *my_data;
  93. #ifdef DEBUG
  94.   ecrit_rapport("alloc_io_channel start\n");
  95. #endif
  96.   ioch = (io_channel)malloc(sizeof(struct struct_io_channel));
  97.   if (ioch==NULL)
  98.     return NULL;
  99.   memset(ioch, 0, sizeof(struct struct_io_channel));
  100.   ioch->magic = EXT2_ET_MAGIC_IO_CHANNEL;
  101.   ioch->manager = my_io_manager;
  102.   ioch->name = (char *)malloc(strlen(partition->name)+1);
  103.   if (ioch->name==NULL) {
  104.       free(ioch);
  105.       return NULL;
  106.   }
  107.   strncpy(ioch->name, partition->name,sizeof(ioch->name));
  108.   my_data=MALLOC(sizeof(*my_data));
  109.   my_data->partition=partition;
  110.   my_data->disk_car=disk_car;
  111.   ioch->private_data = my_data;
  112.   ioch->block_size = 1024; /* The smallest ext2fs block size */
  113.   ioch->read_error = 0;
  114.   ioch->write_error = 0;
  115. #ifdef DEBUG
  116.   ecrit_rapport("alloc_io_channel end\n");
  117. #endif
  118.   return ioch;
  119. }
  120.  
  121. static errcode_t my_open(const char *dev, int flags, io_channel *channel)
  122. {
  123.   *channel = (io_channel*)dev;
  124. #ifdef DEBUG
  125.   ecrit_rapport("my_open done\n");
  126. #endif
  127.   return 0;
  128. }
  129.  
  130. static errcode_t my_close(io_channel channel)
  131. {
  132.   FREE(channel->private_data);
  133.   FREE(channel->name);
  134.   FREE(channel);
  135. #ifdef DEBUG
  136.   ecrit_rapport("my_close done\n");
  137. #endif
  138.   return 0;
  139. }
  140.  
  141. static errcode_t my_set_blksize(io_channel channel, int blksize)
  142. {
  143.   channel->block_size = blksize;
  144. #ifdef DEBUG
  145.   ecrit_rapport("my_set_blksize done\n");
  146. #endif
  147.   return 0;
  148. }
  149.  
  150. static errcode_t my_read_blk(io_channel channel, unsigned long block, int count, void *buf)
  151. {
  152.   size_t size;
  153.   t_my_data *my_data=(t_my_data*)channel->private_data;
  154.   EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
  155.  
  156.   size = (count < 0) ? -count : count * channel->block_size;
  157. #ifdef DEBUG
  158.   ecrit_rapport("my_read_blk start\n");
  159.   ecrit_rapport("size=%u, block=%u name=%s\n",size,block,my_data->partition->name);
  160. #endif
  161.   if(my_data->disk_car->read(my_data->disk_car,size/512,buf,my_data->partition->lba+(block*channel->block_size/512))!=0)
  162.     return 1;
  163. #ifdef DEBUG
  164.   ecrit_rapport("my_read_blk done\n");
  165. #endif
  166.   return 0;
  167. }
  168.  
  169. static errcode_t my_write_blk(io_channel channel, unsigned long block, int count, const void *buf)
  170. {
  171.   t_my_data *my_data=(t_my_data*)channel;
  172.   EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
  173. /* if(my_data->disk_car->write(my_data->disk_car,count*channel->block_size/512,buf,my_data->partition->lba+(block*channel->block_size/512))!=0) */
  174.     return 1;
  175. /* return 0; */
  176. }
  177.  
  178. static errcode_t my_flush(io_channel channel)
  179. {
  180.   return 0;
  181. }
  182.  
  183. static int list_dir_proc(struct ext2_dir_entry *dirent,
  184.              int    offset,
  185.              int    blocksize,
  186.              char    *buf,
  187.              void    *private)
  188. {
  189.   struct ext2_inode    inode;
  190.   ext2_ino_t        ino;
  191.   unsigned int        thislen;
  192.   struct list_dir_struct *ls = (struct list_dir_struct *) private;
  193.   t_file_data *new_file=MALLOC(sizeof(*new_file));
  194.   new_file->prev=ls->current_file;
  195.   new_file->next=NULL;
  196.  
  197.   thislen = ((dirent->name_len & 0xFF) < EXT2_NAME_LEN) ?
  198.     (dirent->name_len & 0xFF) : EXT2_NAME_LEN;
  199.   if(thislen>DIR_NAME_LEN)
  200.     thislen=DIR_NAME_LEN;
  201.   memcpy(new_file->name, dirent->name, thislen);
  202.   new_file->name[thislen] = '\0';
  203.   ino = dirent->inode;
  204.   if (ino) {
  205.     if (ext2fs_read_inode(ls->current_fs,ino, &inode))
  206.     {
  207.       FREE(new_file);
  208.       FREE(new_file);
  209.       return 0;
  210.     }
  211.   } else {
  212.     memset(&inode, 0, sizeof(struct ext2_inode));
  213.   }
  214.   new_file->filestat.st_dev=0;
  215.   new_file->filestat.st_ino=ino;
  216.   new_file->filestat.st_mode=inode.i_mode;
  217.   new_file->filestat.st_nlink=inode.i_links_count;
  218.   new_file->filestat.st_uid=inode.i_uid;
  219.   new_file->filestat.st_gid=inode.i_gid;
  220.   new_file->filestat.st_rdev=0;
  221.   new_file->filestat.st_size=LINUX_S_ISDIR(inode.i_mode)?inode.i_size:
  222.     inode.i_size| ((__u64)inode.i_size_high << 32);
  223.   new_file->filestat.st_blksize=blocksize;
  224. #ifndef DJGPP
  225.   new_file->filestat.st_blocks=inode.i_blocks;
  226. #endif
  227.   new_file->filestat.st_atime=inode.i_atime;
  228.   new_file->filestat.st_mtime=inode.i_mtime;
  229.   new_file->filestat.st_ctime=inode.i_ctime;
  230.   if(ls->current_file!=NULL)
  231.     ls->current_file->next=new_file;
  232.   else
  233.     ls->dir_list=new_file;
  234.   ls->current_file=new_file;
  235.   return 0;
  236. }
  237.  
  238. t_file_data *ext2_dir(t_param_disk *disk_car, const t_diskext *partition, t_dir_data *dir_data, const unsigned long int cluster);
  239. t_file_data *ext2_dir(t_param_disk *disk_car, const t_diskext *partition, t_dir_data *dir_data, const unsigned long int cluster)
  240. {
  241.   struct list_dir_struct *ls=(struct list_dir_struct*)dir_data->private_dir_data;
  242.   ls->dir_list=NULL;
  243.   ls->current_file=NULL;
  244.   ext2fs_dir_iterate(ls->current_fs, cluster, ls->flags, 0, list_dir_proc, ls);
  245.   return ls->dir_list;
  246. }
  247.  
  248. int dir_partition_ext2(WINDOW *window,t_param_disk *disk_car,t_diskext *partition, const int debug)
  249. {
  250.   errcode_t       retval;
  251.   static struct list_dir_struct ls;
  252.   io_channel ioch;
  253.   ls.dir_list=NULL;
  254.   ls.current_file=NULL;
  255.   aff_buffer(BUFFER_RESET,"Q");
  256.   wmove(window,4,0);
  257.   aff_part(window,AFF_PART_NL,disk_car,partition);
  258.   ecrit_rapport("\n");
  259.   aff_part_rapport(disk_car,partition);
  260.   ioch=alloc_io_channel(disk_car,partition);
  261.   retval = ext2fs_open (ioch, 0, partition->boot_sector, partition->blocksize, my_io_manager, &ls.current_fs);
  262.   if(retval)
  263.   {
  264.     aff_buffer(BUFFER_ADD,"Can't open ext2fs (retval=%u)\n",retval);
  265.     aff_buffer(BUFFER_DISPLAY,"Q",window);
  266.     return -1;
  267.   }
  268.   ls.flags = 0; /*DIRENT_FLAG_INCLUDE_EMPTY; */
  269.   {
  270.     t_dir_data dir_data;
  271.     dir_data.window=window;
  272.     dir_data.debug=debug;
  273.     dir_data.private_dir_data=&ls;
  274.     dir_data.get_dir=ext2_dir;
  275.     strncpy(dir_data.current_directory,"/",sizeof(dir_data.current_directory));
  276.     dir_partition(disk_car,partition,&dir_data,EXT2_ROOT_INO);
  277.   }
  278.   ext2fs_close (ls.current_fs);
  279.   return 0;
  280. }
  281. #else
  282. #include "types.h"
  283. #include "common.h"
  284. #include "intrface.h"
  285.  
  286. int dir_partition_ext2(WINDOW *window,t_param_disk *disk_car,t_diskext *partition)
  287. {
  288.   aff_buffer(BUFFER_RESET,"Q");
  289.   wmove(stdscr,5,0);
  290.   aff_part(window,AFF_PART_NONL,disk_car,partition);
  291.   aff_part_rapport(disk_car,partition);
  292.   aff_buffer(BUFFER_ADD,"Recompile with e2fsprogs library");
  293.   aff_buffer(BUFFER_DISPLAY,"Q",window);
  294.   return 0;
  295. }
  296. #endif
  297.